package Services

import (
	"errors"
	"gorm.io/gorm"
	"minititok/Entities"
	"minititok/databases"
)

func FindFiveOrderByLikes(username string) ([]Entities.Video, error) {
	var videos []Entities.Video
	subQuery := databases.DB.Model(&Entities.HadWatch{}).
		Select("CAST(av AS UNSIGNED)").
		Where("username = ?", username)
	err := databases.DB.Where("av NOT IN (?)", gorm.Expr("?", subQuery)).
		Order("likes DESC").
		Limit(5).
		Find(&videos).
		Error
	return videos, err
}

func FindFiveNotWatchedWithPrefix(username string) ([]Entities.Video, error) {
	var videos []Entities.Video

	// 子查询：hadWatch.av 列中存的是 "123" 这种格式
	subQuery := databases.DB.Model(&Entities.HadWatch{}).
		Select("CAST(av AS UNSIGNED)").
		Where("username = ?", username)

	// 主查询：过滤掉用户已看过的
	err := databases.DB.Model(&Entities.Video{}).
		Where("av NOT IN (?)", gorm.Expr("?", subQuery)).
		Order("likes DESC").
		Limit(5).
		Find(&videos).Error

	return videos, err
}

func FindVideoByAV(av int64) (*Entities.Video, error) {
	var video Entities.Video
	err := databases.DB.Where("av = ?", av).First(&video).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return nil, nil // 没找到返回 nil，符合Django的 None
	}
	if err != nil {
		return nil, err // 其他错误直接返回
	}
	return &video, nil
}

func GetCountByAuthor(author string) (int64, error) {
	var count int64
	err := databases.DB.Model(&Entities.Video{}).Where("author = ?", author).Count(&count).Error
	return count, err
}

func DeleteByAV(av int64) (bool, error) {
	err := databases.DB.Where("av = ?", av).Delete(&Entities.Video{}).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return false, nil
	}
	if err != nil {
		return false, err
	}
	return true, nil
}

func GetOneSelfVideoBeforeTime(username string, targetTime string) ([]Entities.Video, error) {
	var videos []Entities.Video
	err := databases.DB.
		Where("author = ? AND create_date < ?", username, targetTime).
		Order("create_date DESC").
		Limit(5).
		Find(&videos).Error
	if err != nil {
		return nil, err
	}
	return videos, nil
}

func GetOneselfVideoByPage(username string, page, pageSize int) ([]Entities.Video, error) {
	var videos []Entities.Video
	offset := (page - 1) * pageSize
	err := databases.DB.Where("author = ?", username).
		Order("create_date DESC").
		Offset(offset).
		Limit(pageSize).
		Find(&videos).Error
	if err != nil {
		return nil, err
	}
	return videos, nil
}

func CreateVideo(video *Entities.Video) error {
	return databases.DB.Create(video).Error
}

func CountLikes(video *Entities.Video) error {
	var count int64
	err := databases.DB.Model(&Entities.Like{}).
		Where("av=? AND liked=?", video.Av, true).
		Count(&count).
		Error
	if err != nil {
		return err
	}
	video.Likes = uint64(count)
	databases.DB.Model(video).Update("likes", video.Likes)
	return nil
}

func CountComments(video *Entities.Video) error {
	var count int64
	err := databases.DB.Model(&Entities.Comment{}).
		Where("av=?", video.Av).
		Count(&count).
		Error
	if err != nil {
		return err
	}
	video.Comments = uint64(count)
	databases.DB.Model(video).Update("comments", video.Comments)
	return nil
}

func CountFavorites(video *Entities.Video) error {
	var count int64
	err := databases.DB.Model(&Entities.Favorite{}).
		Where("av=? And favorited=?", video.Av, true).
		Count(&count).
		Error
	if err != nil {
		return err
	}
	video.Collects = uint64(count)
	databases.DB.Model(video).Update("collects", video.Collects)
	return nil
}
